from PIL import Image
import numpy as np
import cv2
import numpy as np
def pixelate_opencv(image_path, output_path, pixel_size=8):
    """
    基础像素化方法
    :param pixel_size: 像素块大小（值越大像素感越强）
    """
    # 读取图像
    img = cv2.imread(image_path)
    
    # 获取原始尺寸
    h, w = img.shape[:2]
    
    # 计算缩小后的尺寸
    temp_h = h // pixel_size
    temp_w = w // pixel_size
    
    # 1. 缩小图像（关键步骤）
    small_img = cv2.resize(img, (temp_w, temp_h), interpolation=cv2.INTER_LINEAR)
    
    # 2. 放大回原尺寸
    pixel_img = cv2.resize(small_img, (w, h), interpolation=cv2.INTER_NEAREST)
    
    # 保存结果
    cv2.imwrite(output_path, pixel_img)
    return pixel_img

def retro_game_style(image_path, output_path, pixel_size=8, edge_threshold=100):
    # 基础像素化
    img = cv2.imread(image_path)
    h, w = img.shape[:2]
    small = cv2.resize(img, (w//pixel_size, h//pixel_size), interpolation=cv2.INTER_LINEAR)
    pixel_img = cv2.resize(small, (w, h), interpolation=cv2.INTER_NEAREST)
    
    # 边缘检测
    gray = cv2.cvtColor(pixel_img, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, edge_threshold, edge_threshold*2)
    
    # 添加黑色轮廓
    pixel_img[edges != 0] = [0, 0, 0]
    
    cv2.imwrite(output_path, pixel_img)
    return pixel_img


def pixelate_advanced(image_path, output_path, pixel_size=8, color_num=16):
    """
    高级像素化（带颜色量化）
    :param color_num: 颜色数量（值越小像素感越强）
    """
    img = Image.open(image_path)
    
    # 1. 缩小图像
    small_img = img.resize(
        (img.width // pixel_size, img.height // pixel_size),
        Image.NEAREST
    )
    
    # 2. 颜色量化
    if color_num < 256:
        small_img = small_img.convert("P", palette=Image.ADAPTIVE, colors=color_num)
        small_img = small_img.convert("RGB")
    
    # 3. 放大回原尺寸
    pixel_img = small_img.resize(img.size, Image.NEAREST)
    
    pixel_img.save(output_path)
    return pixel_img
from sklearn.cluster import KMeans
import numpy as np

def kmeans_pixelate(image_path, output_path, pixel_size=8, n_colors=8):
    img = cv2.imread(image_path)
    h, w = img.shape[:2]
    
    # 1. 缩小图像
    small = cv2.resize(img, (w//pixel_size, h//pixel_size), 
                      interpolation=cv2.INTER_AREA)
    
    # 2. 颜色聚类
    pixels = small.reshape(-1, 3)
    kmeans = KMeans(n_clusters=n_colors, random_state=0).fit(pixels)
    new_colors = kmeans.cluster_centers_[kmeans.labels_]
    
    # 3. 重建图像
    quantized_img = new_colors.reshape(small.shape).astype(np.uint8)
    pixel_img = cv2.resize(quantized_img, (w, h), interpolation=cv2.INTER_NEAREST)
    
    cv2.imwrite(output_path, pixel_img)
    return pixel_img


pixel_image = pixelate_opencv("content.jpg", "pixel_output.jpg", pixel_size=10)
# 使用示例
pixel_image = pixelate_advanced("style.jpg", "pixel_advanced.jpg", 
                              pixel_size=12, color_num=8)
# 使用示例
retro_image = retro_game_style("content.jpg", "retro_output.jpg", 
                              pixel_size=10, edge_threshold=50)
# 使用示例
kmeans_img = kmeans_pixelate("style.jpg", "kmeans_output.jpg", 
                           pixel_size=12, n_colors=6)